﻿<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../helpproject.xsl" ?>
<topic template="Default" lasteditedby="Geert" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../helpproject.xsd">
  <title translate="true">Using a custom control</title>
  <keywords>
    <keyword translate="true">Behavior</keyword>
    <keyword translate="true">DataWindow</keyword>
    <keyword translate="true">DataWindow&lt;TViewModel&gt;</keyword>
    <keyword translate="true">External controls</keyword>
    <keyword translate="true">MVVM</keyword>
    <keyword translate="true">MVVM behaviors</keyword>
  </keywords>
  <body>
    <header>
      <para styleclass="Heading1"><text styleclass="Heading1" translate="true">Using a custom control</text></para>
    </header>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">In this part of the documentation, the </text><text styleclass="Normal" style="font-style:italic;" translate="true">RadTabItem</text><text styleclass="Normal" translate="true"> of Telerik will be used as an example on how to create a </text><text styleclass="Normal" style="font-style:italic;" translate="true">RadTabItem</text><text styleclass="Normal" translate="true"> that behaves like the </text><text styleclass="Normal" style="font-style:italic;" translate="true">UserControl</text><text styleclass="Normal" translate="true">.</text></para>
    <para styleclass="Heading1"><text styleclass="Heading1" translate="true">Creating the base class with behavior</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">The first thing to do is to create a new base class that accepts a view model type argument. In this example, we will call it </text><text styleclass="Normal" style="font-style:italic;" translate="true">TabItem</text><text styleclass="Normal" translate="true"> (to make it as &quot;external control company independent&quot; as possible). Below is the code for the control definition. The downside of xaml based applications is that you cannot derive from controls or windows that have a partial class defined in xaml. Therefore, all controls and code must be initialized via code as you can see in the code below.</text></para>
    <para styleclass="Code Example"><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// Base class for a control with the Catel mvvm behavior.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;typeparam name=&quot;TViewModel&quot;&gt;The type of the view model.&lt;/typeparam&gt;</text><br/><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">class</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> TabItem : RadTabItem, IUserControl</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">private</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">readonly</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> UserControlLogic _logic;</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// Initializes a new instance of the &lt;see cref=&quot;TabItem{TViewModel}&quot;/&gt; class.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#000000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">TabItem()</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;var</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">viewModelType</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">=</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">GetViewModelType();</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">if</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">(viewModelType</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">==</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">null</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">)</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;{</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160; var</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">viewModelLocator</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">=</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">ServiceLocator.Instance.ResolveType&lt;IViewModelLocator&gt;();</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160; viewModelType</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">=</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">viewModelLocator.ResolveViewModel(GetType());</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160; </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">if</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">(viewModelType</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">==</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">null</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">)</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160; {</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160; &#160; &#160;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">const</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">string</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">error</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">=</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&quot;The view model of the view could not be resolved. Use either the GetViewModelType() method or IViewModelLocator&quot;;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160; &#160; &#160;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">throw</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000000;" translate="true">new</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#ffffff;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">NotSupportedException(error);</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160; &#160; }</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;}</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;_logic = </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">new</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> UserControlLogic(this, viewModelType);</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;_logic.ViewModelChanged += (sender, e) =&gt; ViewModelChanged.SafeInvoke(</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">this</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">, e);</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;_logic.ViewModelPropertyChanged += (sender, e) =&gt; ViewModelPropertyChanged.SafeInvoke(</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">this</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">, e);</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;_logic.PropertyChanged += (sender, e) =&gt; PropertyChanged.SafeInvoke(</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">this</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">, e);</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;SetBinding(RadTabItem.HeaderProperty, </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">new</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> Binding(&quot;Title&quot;));</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; }</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// Gets the view model that is contained by the container.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;value&gt;The view model.&lt;/value&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> IViewModel ViewModel</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; {</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; &#160; &#160;get { </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">return</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> _logic.ViewModel; }</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; }</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// Occurs when the &lt;see cref=&quot;ViewModel&quot;/&gt; property has changed.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">event</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> EventHandler&lt;EventArgs&gt; ViewModelChanged;</text><br/><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// Occurs when a property on the &lt;see cref=&quot;ViewModel&quot;/&gt; has changed.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">event</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> EventHandler&lt;PropertyChangedEventArgs&gt; ViewModelPropertyChanged;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// Occurs when a property on the container has changed.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;/summary&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;remarks&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// This event makes it possible to externally subscribe to property changes of a &lt;see cref=&quot;DependencyObject&quot;/&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// (mostly the container of a view model) because the .NET Framework does not allows us to.</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:normal; font-style:italic; color:#800000;" translate="true">/// &lt;/remarks&gt;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> &#160; </text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">public</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">&#32;</text><text styleclass="Code Example" style="font-weight:bold; font-style:normal; color:#000080;" translate="true">event</text><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true"> EventHandler&lt;PropertyChangedEventArgs&gt; PropertyChanged; &#160; &#160;</text><br/><text styleclass="Code Example" style="font-weight:normal; font-style:normal; color:#000000;" translate="true">}</text></para>
    <para styleclass="Notes"><text styleclass="Notes" translate="true">You would expect an abstract class here, but the designers (both Visual Studio and Expression Blend) can&apos;t handle abstract base classes</text></para>
    <para styleclass="Heading1"><text styleclass="Heading1" translate="true">Using the class</text></para>
    <para styleclass="Normal"><text styleclass="Normal" translate="true">The class can now be used the same as the </text><link displaytype="text" defaultstyle="true" type="topiclink" href="T_Catel_Windows_Controls_UserControl" styleclass="Normal" translate="true">UserControl</link><text styleclass="Normal" translate="true"> class. For more information, see </text><link displaytype="text" defaultstyle="true" type="topiclink" href="UserControl_explained" styleclass="Normal" translate="true">UserControl explained</link><text styleclass="Normal" translate="true">.</text></para>
  </body>
</topic>
